package com.ckzp.core.file;

import com.ckzp.core.Results;
import com.ckzp.core.util.StringUtil;
import com.ckzp.core.validate.FileValidate;
import com.jfinal.kit.FileKit;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by 51594 on 2022/7/28.
 */
public class FileControl {
    /**
     * 文件路经
     */
    private String path;


    /**
     * 根路经
     */
    private String rootPath;

    /**
     * 文件名
     */
    private String fileName;
    /**
     * 文件对象
     */
    private File myFile;

    /**
     * 取得文件
     *
     * @return
     */
    public File getMyFile() {
        return myFile;
    }

    /**
     * @param myFile
     */
    public void setMyFile(File myFile) {
        this.myFile = myFile;
    }

    /**
     *
     */
    public FileControl() {
    }

    public static FileControl n() {
        return new FileControl();
    }

    public static FileControl n(String path) {
        path = FileValidate.validatePath(path);
        return new FileControl(new File(path));
    }

    /**
     * @param request
     * @param path
     * @param fileName
     */
    public FileControl(HttpServletRequest request, String path, String fileName) {
        this.rootPath = request.getRealPath("/");
        path = StringUtil.replace(path, "\"", "/");
        path = StringUtil.replace(path, "//", "/");
        if (!StringUtil.isEndWith(path, "/")) path += "/";
        this.path = path;
        this.fileName = fileName;
        this.myFile = new File(rootPath + path + fileName);
    }

    /**
     * @param request
     * @param path    路经
     */
    public FileControl(HttpServletRequest request, String path) {
        this.rootPath = request.getRealPath("/");
        path = StringUtil.replace(path, "\"", "/");
        path = StringUtil.replace(path, "//", "/");
        if (!StringUtil.isEndWith(path, "/")) path += "/";
        this.path = path;
        this.myFile = new File(rootPath + path);
    }

    /**
     * @param file
     */
    public FileControl(File file) {
        this.myFile = file;
    }

    /**
     * * 创建文件
     *
     * @return
     * @throws FileUtilException
     */
    public boolean createFile() throws Exception {
        if (myFile == null) {
            throw new FileNotFoundException();
        } else if (myFile.isDirectory()) {
            createDirectory();
            return true;
        } else {
            try {
                createDirectory();
                myFile.createNewFile();
                return true;
            } catch (IOException e) {
                throw e;
            }
        }
    }

    /**
     * 删除文件
     *
     * @return
     * @throws FileUtilException
     */
    public boolean deleteFile() throws FileUtilException {
        if (this.myFile == null)
            throw new FileUtilException("file not found");
        else if (myFile.isDirectory())
            throw new FileUtilException("this path is a directory");
        else if (myFile.isFile())
            return myFile.delete();
        else
            throw new FileUtilException("unknow error");
    }

    /**
     * b取得文件列表
     *
     * @return
     */
    public List getFileList() {
        List l = new ArrayList();
        if (myFile.isDirectory()) {
            File[] f = myFile.listFiles();
            for (int k = 0; k < f.length; k++) {
                if (f[k].isFile()) {
                    l.add(f[k]);
                }
            }
        }
        return l;
    }

    /**
     * 创建文件夹
     *
     * @return
     */
    public boolean createDirectory() {
        boolean re = false;
        File tempFile = null;
        String tempFilePath = "";
        if (this.myFile.isFile())
            tempFile = myFile;
        else
            tempFile = myFile.getParentFile();
        String path = StringUtil.getString(tempFile.getAbsolutePath(), "");
        path = StringUtil.replace(path, "\\", "/");
        path = StringUtil.replace(path, "\\", "/");
        String[] fileName = StringUtil.split(path, "/");
        for (int kk = 0; kk < fileName.length; kk++) {
            tempFilePath += fileName[kk] + "/";
            if (!tempFilePath.startsWith("/") && tempFilePath.indexOf(":") != 1) {
                tempFilePath = "/" + tempFilePath;
            }
            tempFile = new File(tempFilePath);
            re = tempFile.mkdir();
        }
        return re;
    }

    /**
     * 删除文件夹
     *
     * @return
     * @throws FileUtilException
     */
    public boolean deleteDirectory() throws FileUtilException {
        if (this.myFile == null)
            throw new FileUtilException("file not found");
        else if (myFile.isFile())
            throw new FileUtilException(" this is a directory");
        else if (myFile.isDirectory())
            return FileUtil.deleteDirectory(this.myFile);
        else
            throw new FileUtilException("unknow error");
    }

    /**
     * 更更txt文件
     * *
     *
     * @param fileText
     * @return
     * @throws FileUtilException
     */
    public boolean updateFile(String fileText) throws FileUtilException {
        boolean re = myFile.delete();
        if (writeFile(fileText))
            return re;
        else
            return false;
    }


    /**
     * 写文件
     *
     * @param str
     * @return
     * @throws FileUtilException
     */
    public synchronized boolean writeFile2(String str) throws FileUtilException {
        String tempStr = "";
        if (myFile == null) {
            throw new FileUtilException("file not found");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("this is not a file");
        }
        try {
            //  BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(this.myFile), "GBK"));
            // BufferedReader in = new BufferedReader(new StringReader(str));
            BufferedWriter fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.myFile), "utf-8"));
            PrintWriter out = new PrintWriter(fout);
            // PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(this.myFile)));
            //while ((tempStr = in.readLine()) != null) {
            out.println(str);
            //}
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new FileUtilException("io error", e);
        }
        return true;
    }

    /**
     * @param str
     * @return
     * @throws FileUtilException
     */
    public synchronized boolean writeFile(String str) throws FileUtilException {
        if (myFile == null) {
            throw new FileUtilException("文件为空");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("不是有效文件");
        }
        try {
            FileOutputStream fos = new FileOutputStream(this.myFile);
            BufferedOutputStream out = new BufferedOutputStream(fos);
            out.write(str.getBytes("UTF-8"));
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new FileUtilException("未知错误", e);
        }
        return true;
    }

    /**
     * *
     *
     * @param str
     * @return
     * @throws FileUtilException
     */
    public boolean writeFile(String str, String charset) throws FileUtilException {
        String tempStr = "";
        if (myFile == null) {
            throw new FileUtilException("��ָ��Ҫ������ļ�");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("�Բ�����ָ���Ĳ����ļ�");
        }
        try {
            //  BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(this.myFile), "GBK"));
//            BufferedWriter fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.myFile), charset));
//            PrintWriter out = new PrintWriter(fout);
//            // PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(this.myFile)));
//            //while ((tempStr = in.readLine()) != null) {
//            out.println(str);
            //}

            FileOutputStream os = new FileOutputStream(this.myFile);
            OutputStreamWriter ow = new OutputStreamWriter(os, charset);
            BufferedWriter writer = new BufferedWriter(ow);
            writer.write(str);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new FileUtilException("io error", e);
        }
        return true;
    }


    /**
     * д���ļ�
     *
     * @param is
     * @return
     * @throws FileUtilException
     */
    public synchronized boolean writeFile(InputStream is) throws FileUtilException {
        String tempStr = "";
        if (myFile == null) {
            throw new FileUtilException("file not found");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("it is not file");
        }
        try {
            FileOutputStream out = new FileOutputStream(myFile);
            byte data[] = new byte[is.available()];
            int read = is.read(data);
            out.write(data);
            is.close();
            out.close();
        } catch (IOException e) {
            throw new FileUtilException("unknow error", e);
        }
        return true;
    }

    ;

    /**
     * @return
     * @throws FileUtilException
     */
    public synchronized String readFile2() throws FileUtilException {
        String tempStr = "", tempStr2 = "";
        if (myFile == null) {
            throw new FileUtilException("��ָ��Ҫ��ȡ���ļ�");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("�Բ������ȡ�Ĳ����ļ�");
        }
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(myFile), "UTF-8"));
            while ((tempStr = in.readLine()) != null) {
                tempStr2 += tempStr + "\n";
            }
            in.close();
        } catch (IOException e) {
            throw new FileUtilException("��ȡ�ļ�ʧ��", e);
        }
        return tempStr2;
    }


    /**
     * @return
     * @throws FileUtilException
     */
    public synchronized String readFile() throws FileUtilException {
        StringBuffer sb = new StringBuffer();
        BufferedInputStream bufferedInput = null;
        byte[] buffer = new byte[1024];
        if (myFile == null) {
            throw new FileUtilException("��ָ��Ҫ��ȡ���ļ�");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("�Բ������ȡ�Ĳ����ļ�");
        }
        try {
            bufferedInput = new BufferedInputStream(new FileInputStream(myFile));
            int bytesRead = 0;
            while ((bytesRead = bufferedInput.read(buffer)) != -1) {
                StringBuffer chunk = new StringBuffer(new String(buffer, 0, bytesRead, "UTF-8"));
                sb.append(chunk);
            }
            bufferedInput.close();
        } catch (IOException e) {
            throw new FileUtilException("��ȡ�ļ�ʧ��", e);
        }
        return sb.toString();
    }

    /**
     * ��StringBuffer����ʽ�õ��ļ�
     *
     * @return
     * @throws FileUtilException
     */
    public StringBuffer readFileBuffer() throws FileUtilException {
        StringBuffer sb = new StringBuffer();
        BufferedInputStream bufferedInput = null;
        byte[] buffer = new byte[1024];
        if (myFile == null) {
            throw new FileUtilException("");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("");
        }
        try {
            bufferedInput = new BufferedInputStream(new FileInputStream(myFile));
            int bytesRead = 0;
            while ((bytesRead = bufferedInput.read(buffer)) != -1) {
                String chunk = new String(buffer, 0, bytesRead, "UTF-8");
                sb.append(chunk);
            }
            bufferedInput.close();
        } catch (IOException e) {
            throw new FileUtilException("��ȡ�ļ�ʧ��", e);
        } finally {
            safeCloseOutputStream(bufferedInput);
        }
        return sb;
    }

    private static void safeCloseOutputStream(final BufferedInputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    private static void safeCloseInputStream(final InputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }


    private static void safeCloseOutputStream(final OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }


    /**
     * ��StringBuffer����ʽ�õ��ļ�
     *
     * @return
     * @throws FileUtilException
     */
    public StringBuffer readFileBuffer2() throws FileUtilException {
        StringBuffer tempStr = new StringBuffer();
        String line = "";
        if (myFile == null) {
            throw new FileUtilException("��ָ��Ҫ��ȡ���ļ�");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("�Բ������ȡ�Ĳ����ļ�");
        }
        try {
            BufferedReader in = new BufferedReader(new FileReader(this.myFile));
            while ((line = in.readLine()) != null) {
                tempStr.append(line + "\n");
            }
            in.close();
        } catch (IOException e) {
            throw new FileUtilException("д���ļ�ʧ��", e);
        }
        return tempStr;
    }

    /**
     * ��StringBuffer����ʽ�õ��ļ�
     *
     * @return
     * @throws FileUtilException
     */
    public StringBuffer readFileBuffer(String charset) throws FileUtilException {
        StringBuffer tempStr = new StringBuffer();
        String line = "";
        if (myFile == null) {
            throw new FileUtilException("��ָ��Ҫ��ȡ���ļ�");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("�Բ������ȡ�Ĳ����ļ�");
        }
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(myFile), charset));
            while ((line = in.readLine()) != null) {
                tempStr.append(line + "\n");
            }
            in.close();
        } catch (IOException e) {
            throw new FileUtilException("д���ļ�ʧ��", e);
        }
        return tempStr;
    }

    /**
     * ��ȡ�ļ�����
     *
     * @return
     * @throws FileUtilException
     */
    public byte[] readFileByte() throws FileUtilException {
        String tempStr = "", tempStr2 = "";
        if (myFile == null) {
            throw new FileUtilException("��ָ��Ҫ��ȡ���ļ�");
        } else if (!myFile.isFile()) {
            throw new FileUtilException("�Բ������ȡ�Ĳ����ļ�");
        }
        try {
            BufferedReader in = new BufferedReader(new FileReader(this.myFile));
            while ((tempStr = in.readLine()) != null) {
                tempStr2 += tempStr;
            }
            in.close();
        } catch (IOException e) {
            throw new FileUtilException("д���ļ�ʧ��", e);
        }
        return tempStr2.getBytes();
    }

    /**
     * @param urls
     * @return
     */
    public Results saveFileFromUrl(String urls) {
        OutputStream os = null;
        InputStream is = null;
        try {
            URL url = new URL(urls);
            URLConnection con = url.openConnection();
            con.setConnectTimeout(5 * 1000);
            is = con.getInputStream();
            byte[] bs = new byte[1024];
            int len;
            createDirectory();
            os = new FileOutputStream(myFile);
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            os.close();
            is.close();
            return new Results(0);
        } catch (Exception e) {
            e.printStackTrace();
            return new Results(9, "下载失败", e.toString());
        } finally {
            safeCloseInputStream(is);
            safeCloseOutputStream(os);
        }
    }

    public static void testwrite() {
        StringBuffer str1 = new StringBuffer("中文\\r\\n");
        StringBuffer str = new StringBuffer("测评\\r\\n");
        int count = 10;
        int count1 = 1000;

        try {
            FileControl fc = new FileControl(new File("c://1.txt"));
            fc.createFile();
            for (int i = 0; i < count; i++) {
                str.append(str1);
            }
            long cc = System.currentTimeMillis();
            for (int i = 0; i < count1; i++) {
                fc = new FileControl(new File("c:///1/1.txt" + i));
                fc.createFile();
                fc.writeFile(str.toString());
            }
            System.out.println("writeFile=" + (System.currentTimeMillis() - cc));
            cc = System.currentTimeMillis();
            for (int i = 0; i < count1; i++) {
                fc = new FileControl(new File("c://2/2.txt" + i));
                fc.createFile();
                fc.writeFile2(str.toString());
            }
            System.out.println("writeFile2=" + (System.currentTimeMillis() - cc));
        } catch (Exception e) {
        } finally {
        }
    }


    public Results appendFile(String content) {
        long begin = System.currentTimeMillis();
        try {
            RandomAccessFile randomFile = new RandomAccessFile(myFile, "rw");
            long fileLength = randomFile.length();
            randomFile.seek(fileLength);
            randomFile.write(content.getBytes("GB2312"));
            randomFile.close();
            return new Results(0, "用时:" + (System.currentTimeMillis() - begin) + "ms");
        } catch (IOException e) {
            e.printStackTrace();
            return new Results(9, e.getMessage(), "用时:" + (System.currentTimeMillis() - begin) + "ms");
        }
    }

    public Results appendFileNewLineUTF(String content) {
        long begin = System.currentTimeMillis();
        try {
            RandomAccessFile randomFile = new RandomAccessFile(myFile, "rw");
            long fileLength = randomFile.length();
            randomFile.seek(fileLength);
            randomFile.writeBytes(content);
            randomFile.writeBytes("\n");
            randomFile.close();
            return new Results(0, "用时:" + (System.currentTimeMillis() - begin) + "ms");
        } catch (IOException e) {
            e.printStackTrace();
            return new Results(9, e.getMessage(), "用时:" + (System.currentTimeMillis() - begin) + "ms");
        }
    }

    public Results appendFileUTF(String content) {
        long begin = System.currentTimeMillis();
        try {
            RandomAccessFile randomFile = new RandomAccessFile(myFile, "rw");
            long fileLength = randomFile.length();
            randomFile.seek(fileLength);
            randomFile.writeUTF(content);
            randomFile.close();
            return new Results(0, "用时:" + (System.currentTimeMillis() - begin) + "ms");
        } catch (IOException e) {
            e.printStackTrace();
            return new Results(9, e.getMessage(), "用时:" + (System.currentTimeMillis() - begin) + "ms");
        }
    }

    public Results appendFile2(String content) {
        long begin = System.currentTimeMillis();
        try {
            //打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
            FileWriter writer = new FileWriter(myFile, true);
            writer.write(content);
            writer.close();
            return new Results(0, "用时:" + (System.currentTimeMillis() - begin) + "ms");
        } catch (IOException e) {
            e.printStackTrace();
            return new Results(9, e.getMessage(), "用时:" + (System.currentTimeMillis() - begin) + "ms");
        }
    }


    public static void main(String[] arg) {
        // testwrite();
        FileControl fc = new FileControl();
        fc.setMyFile(new File("d:/1.txt"));
        fc.appendFile("ddddd中文");
    }
}
